home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / demos / procdemo / modelfuns.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-10  |  12.9 KB  |  419 lines

  1. #ifndef lint
  2. static char SccsId[]= "@(#)modelfuns.c    V1.13    3/17/95";
  3. #endif
  4.  
  5. /* modelfuns.c */
  6.  
  7. #include "std.h"
  8. #include "dvstd.h"
  9. #include "dvtools.h"
  10. #include "VUfundecl.h"
  11. #include "VGfundecl.h"
  12. #include "prc_fundecl.h"
  13.  
  14. #ifndef WINNT
  15. #include <time.h>
  16. #endif /* WINNT */
  17.  
  18.  
  19. /* model "constants" */
  20. LOCAL FLOAT STGCAP = 100;
  21. LOCAL FLOAT RVCAP = 1000;
  22. LOCAL FLOAT STMTMP = 200;
  23. LOCAL FLOAT STMDELTA = 50;
  24. LOCAL FLOAT OUTTMP = 70;
  25. LOCAL FLOAT STMTRAN = .1F;
  26. LOCAL FLOAT PIPEVOL = 2;
  27. LOCAL FLOAT ITERLEN = 2;
  28. LOCAL FLOAT VALVEINCR = 0.2F;
  29. LOCAL FLOAT STM_CTL_PARAM = 5;
  30. LOCAL FLOAT INTMPMIN = 0.33F;
  31. LOCAL FLOAT INFLOWMIN = 0.33F;
  32. LOCAL FLOAT OUT_TOLER = 0.1F;
  33. LOCAL FLOAT VALVESTICKINESS = 0.05F;
  34. LOCAL FLOAT UNSTICKINESS = 0.3F;
  35.  
  36. typedef struct
  37. {
  38.   ULONG time, itercount;
  39.   FLOAT hour, minute, second;
  40.   FLOAT in_tmp, in_flow, stg_tmp, stg_vol, stg_of_vol, rv_tmp, rv_vol, wst_vol, out_vol, tot_tmp_err, in_valve, stg_valve, stm_valve, out_valve, wst_valve, stuck_in_valve, stuck_stg_valve, stuck_stm_valve, stuck_out_valve, stuck_wst_valve, stm_tmp, stg_of_flow, stg_out_flow, rv_of_flow, wst_flow, out_flow, avg_tmp_err, cur_tmp_err, pct_tot_wst, avg_tmp_good, cur_tmp_good, pct_wst_good, raw_flow[50], produce_flow[50];
  41. } MODELVARS;
  42.  
  43. LOCAL MODELVARS current, last;  /* current and last values */
  44. LOCAL FLOAT total_input = 0;
  45. LOCAL FLOAT total_wst_n_of = 0;
  46.  
  47. LOCAL DV_BOOL inited_once = NO;
  48.  
  49. /***************** Begin Function Declarations *************/
  50. LOCAL  double rand01 V_P_((void));
  51. LOCAL  void fmod01 V_P_((float *f, double modulus));
  52. LOCAL  void getinputs V_P_((void));
  53. LOCAL  double make_100_goodness V_P_((double badness, double maximum_bad));
  54. LOCAL  void getmodelvars V_P_((void));
  55. LOCAL  void changevalve V_P_((float *valve_ptr, int delta));
  56. LOCAL  void unsticktry2 V_P_((float *stuckness_ptr, float *valve_ptr, int delta));
  57. LOCAL  void tryvalve2 V_P_((float *stuckness_ptr, float *valve_ptr, int delta));
  58. /***************** End Function Declarations *************/
  59.  
  60. void MDLinit 
  61. V_P_ ((void))
  62. {
  63.   INT i;
  64.   FILE *const_file;
  65.  
  66.   current.time = 0;
  67.   current.itercount = 0;
  68.   current.in_tmp = 0.0;
  69.   current.in_flow = 0.0;
  70.   current.stg_vol = 0.0;
  71.   current.stg_tmp = 0.0;
  72.   current.stg_of_vol = 0.0;
  73.   current.rv_vol = 0.0;
  74.   current.rv_tmp = 0.0;
  75.   current.stm_tmp = 0.0;
  76.   current.wst_vol = 0.0;
  77.   current.out_vol = 0.0;
  78.   current.tot_tmp_err = 0.0;
  79.   current.in_valve = 0.0;
  80.   current.stg_valve = 0.0;
  81.   current.stm_valve = 0.0;
  82.   current.wst_valve = 0.0;
  83.   current.out_valve = 0.0;
  84.   current.stg_of_flow = 0.0;
  85.   current.stg_out_flow = 0.0;
  86.   current.rv_of_flow = 0.0;
  87.   current.wst_flow = 0.0;
  88.   current.out_flow = 0.0;
  89.   current.avg_tmp_err = 0.0;
  90.   current.cur_tmp_err = 0.0;
  91.   current.pct_tot_wst = 0.0;
  92.   current.avg_tmp_good = 0.0;
  93.   current.cur_tmp_good = 0.0;
  94.   current.pct_wst_good = 0.0;
  95.  
  96.   for (i = 0; i < 50; i++)
  97.     {
  98.       current.raw_flow[i] = 0.0;
  99.       current.produce_flow[i] = 0.0;
  100.     }
  101.  
  102.   total_input = 0;
  103.   total_wst_n_of = 0;
  104.  
  105.   memcpy(&last, ¤t, sizeof (MODELVARS));
  106.  
  107.   if (!inited_once)
  108.     {
  109.       VUsrand (time (0));
  110.  
  111.       if ((const_file = (FILE *) S_FOPEN ("model.consts", "r")) == 0)
  112.  
  113.         printf ("Couldn't open 'modelast.consts'. Using default values.\n");
  114.       else
  115.         {
  116.           fscanf (const_file, "%f%*s\n%f%*s\n%f%*s\n%f%*s\n%f%*s\n",
  117.                   &STGCAP, &RVCAP, &STMTMP, &STMDELTA, &OUTTMP);
  118.           fscanf (const_file, "%f%*s\n%f%*s\n%f%*s\n%f%*s\n%f%*s\n",
  119.             &STMTRAN, &PIPEVOL, &ITERLEN, &VALVEINCR, &STM_CTL_PARAM);
  120.           fscanf (const_file, "%f%*s\n%f%*s\n%f%*s\n%f%*s\n%f%*s\n",
  121.                   &INTMPMIN, &INFLOWMIN, &OUT_TOLER,
  122.                   &VALVESTICKINESS, &UNSTICKINESS);
  123.         }
  124.  
  125.       inited_once = YES;
  126.     }
  127. }
  128.  
  129.  
  130. LOCAL double rand01 
  131. V_P_ ((void))
  132. {
  133.   return VUfrand ();
  134. }
  135.  
  136.  
  137. LOCAL void 
  138. fmod01 (f, modulus)
  139.      float *f;
  140.      double modulus;
  141. {
  142.   while (*f >= modulus)
  143.     *f = (FLOAT)(*f - modulus);
  144. }
  145.  
  146.  
  147. void MDLupdate 
  148. V_P_ ((void))
  149. {
  150.   current.itercount++;
  151.   getinputs ();
  152.   getmodelvars ();
  153.   memcpy(&last, ¤t, sizeof (MODELVARS));
  154. }
  155.  
  156.  
  157. LOCAL FLOAT raw_flow_offset = 0;
  158.  
  159.  
  160. LOCAL void getinputs 
  161. V_P_ ((void))
  162. {
  163.   INT i, flowoffset;
  164.  
  165.   if (current.in_valve != 0.0)
  166.     {
  167.       current.in_tmp = (FLOAT)(OUTTMP * (INTMPMIN + (1 - INTMPMIN) * rand01 ()));
  168.       current.in_flow =
  169.         (FLOAT)(current.in_valve * PIPEVOL * (INFLOWMIN + (1 - INFLOWMIN) * rand01 ()));
  170.     }
  171.   else
  172.     current.in_flow = 0.0;      /* temp constant if valve closed */
  173.  
  174.   if (current.in_flow > 0.0)
  175.     {
  176.       raw_flow_offset += current.in_flow * 3;
  177.       fmod01 (&raw_flow_offset, 13.0);
  178.       flowoffset = (INT)raw_flow_offset;
  179.       for (i = 0; i < 50; i++)
  180.         {
  181.           if ((i % 13) == flowoffset)
  182.             current.raw_flow[i] = STMTMP;
  183.           else
  184.             current.raw_flow[i] = last.stg_tmp;
  185.         }
  186.     }
  187. }
  188.  
  189.  
  190. LOCAL double 
  191. make_100_goodness (badness, maximum_bad)
  192.      double badness;
  193.      double maximum_bad;
  194. {
  195.   return 100.0 * (maximum_bad - badness) / maximum_bad;
  196. }
  197.  
  198.  
  199. LOCAL FLOAT produce_flow_offset = 0;
  200.  
  201.  
  202. LOCAL void getmodelvars 
  203. V_P_ ((void))
  204. {
  205.   INT i, flowoffset;
  206.  
  207.   /* 1st compute intermediates and outputs from valve settings etc*/
  208.   current.stm_tmp = current.stm_tmp + STM_CTL_PARAM *
  209.     (current.stm_valve * STMTMP - current.stm_tmp);
  210.   current.stm_tmp = S_MIN (STMTMP, current.stm_tmp);
  211.   current.out_flow = S_MAX (0.0F,
  212.                             S_MIN (last.rv_vol,
  213.                                    current.out_valve * PIPEVOL * 0.5F *
  214.                                    (1 + last.rv_vol / RVCAP)));
  215.   if (current.out_flow > 0.0)
  216.     {
  217.       produce_flow_offset += current.out_flow * 3;
  218.       fmod01 (&produce_flow_offset, 13.0);
  219.       flowoffset = (INT)produce_flow_offset;
  220.       for (i = 0; i < 50; i++)
  221.         {
  222.           if ((i % 13) == flowoffset)
  223.             current.produce_flow[i] = STMTMP;
  224.           else
  225.             current.produce_flow[i] = last.rv_tmp;
  226.         }
  227.     }
  228.  
  229.   current.wst_flow = S_MAX (0.0F,
  230.                             S_MIN (last.rv_vol - last.out_flow,
  231.                                    current.wst_valve * PIPEVOL * 0.5F *
  232.                                    (1 + last.rv_vol / RVCAP)));
  233.   current.stg_out_flow = S_MAX (0.0F,
  234.                                 S_MIN (last.stg_vol,
  235.                                    current.stg_valve * PIPEVOL * 0.5F *
  236.                                        (1 + last.stg_vol / STGCAP)));
  237.   current.cur_tmp_err = DV_VIABS (OUTTMP - last.rv_tmp) /
  238.     (3.0F * OUT_TOLER * OUTTMP);
  239.   current.cur_tmp_good = (FLOAT)make_100_goodness (
  240.                                    (0.5F + 0.5F * current.cur_tmp_err) *
  241.                        (0.5F + 0.5F * (1.0F - current.out_valve)) - 0.25F,
  242.                                              1.0F);
  243.   current.tot_tmp_err = last.tot_tmp_err + current.cur_tmp_err;
  244.   current.avg_tmp_err = current.tot_tmp_err / current.itercount;
  245.   current.avg_tmp_good = (FLOAT)make_100_goodness (current.avg_tmp_err, 1.0F);
  246.  
  247.   /* now compute state vars */
  248.   current.stg_vol = S_MAX (0.0F,
  249.                last.stg_vol - current.stg_out_flow + current.in_flow);
  250.   current.stg_of_flow = S_MAX (0.0F, current.stg_vol - STGCAP);
  251.   current.stg_vol = S_MIN (STGCAP, current.stg_vol);
  252.   current.stg_of_vol = last.stg_of_vol + current.stg_of_flow;
  253.  
  254.   if (current.stg_vol > 0.0)
  255.     current.stg_tmp = 0.98F * last.stg_tmp +
  256.       ((last.in_tmp - last.stg_tmp) * current.in_flow) /
  257.       (last.stg_vol + 1);
  258.   else
  259.     current.stg_tmp = 0.0;
  260.  
  261.   current.rv_vol = S_MAX (0.0F, last.rv_vol + current.stg_out_flow -
  262.                           (current.out_flow + current.wst_flow));
  263.   current.rv_of_flow = S_MAX (0.0F, current.rv_vol - RVCAP);
  264.   current.rv_vol = S_MIN (RVCAP, current.rv_vol);
  265.  
  266.   if (current.rv_vol > RVCAP * 0.05)
  267.     {
  268.       current.rv_tmp = 0.995F * last.rv_tmp +
  269.         ((last.stg_tmp - last.rv_tmp) * last.stg_out_flow +
  270.          (last.stm_tmp - last.rv_tmp) * STMTRAN) /
  271.         (last.rv_vol + 1);
  272.       current.rv_tmp = S_MAX (0.0F, current.rv_tmp);
  273.     }
  274.   else if (current.rv_vol > 0.0)
  275.     {
  276.       current.rv_tmp = 0.995F * last.rv_tmp +
  277.         ((last.stg_tmp - last.rv_tmp) * last.stg_out_flow +
  278.          (last.stm_tmp - last.rv_tmp) * STMTRAN * 0.2F) /
  279.         (last.rv_vol + 1);
  280.       current.rv_tmp = S_MAX (0.0F, current.rv_tmp);
  281.     }
  282.   else
  283.     current.rv_tmp = 0.0;
  284.  
  285.   current.wst_vol = last.wst_vol + current.wst_flow + current.rv_of_flow;
  286.   current.out_vol = last.out_vol + current.out_flow;
  287.   total_input = total_input + current.in_flow;
  288.   total_wst_n_of = total_wst_n_of + current.wst_flow +
  289.     current.stg_of_flow + current.rv_of_flow;
  290.   current.pct_tot_wst = total_wst_n_of / (total_input + 0.01F);
  291.   current.pct_wst_good = (FLOAT)make_100_goodness (current.pct_tot_wst, 1.0F);
  292. }
  293.  
  294.  
  295. LOCAL void 
  296. changevalve (valve_ptr, delta)
  297.      float *valve_ptr;
  298.      int delta;
  299. {
  300.   if (delta > 0)
  301.     *valve_ptr = S_MIN (1.0F, *valve_ptr + VALVEINCR);
  302.   else
  303.     *valve_ptr = S_MAX (0.0F, *valve_ptr - VALVEINCR);
  304. }
  305.  
  306.  
  307. LOCAL void 
  308. unsticktry2 (stuckness_ptr, valve_ptr, delta)
  309.      float *stuckness_ptr;
  310.      float *valve_ptr;
  311.      int delta;
  312. {
  313.   if (rand01 ()< UNSTICKINESS)
  314.     *stuckness_ptr = 0;
  315. }
  316.  
  317.  
  318. LOCAL void 
  319. tryvalve2 (stuckness_ptr, valve_ptr, delta)
  320.      float *stuckness_ptr;
  321.      float *valve_ptr;
  322.      int delta;
  323. {
  324.   if (rand01 ()< VALVESTICKINESS)
  325.     *stuckness_ptr = 1;
  326.   else
  327.     changevalve (valve_ptr, delta);
  328. }
  329.  
  330.  
  331. void 
  332. MDLchangevalve (valve_name, delta)
  333.      char *valve_name;
  334.      int delta;
  335. {
  336.   if ((strcmp (valve_name, "valve_out") == 0) ||
  337.       (strcmp (valve_name, "valve_out_stuck") == 0))
  338.     if (current.stuck_out_valve == 0)
  339.       tryvalve2 (¤t.stuck_out_valve, ¤t.out_valve, delta);
  340.     else
  341.       unsticktry2 (¤t.stuck_out_valve, ¤t.out_valve, delta);
  342.   else if ((strcmp (valve_name, "valve_stm") == 0) ||
  343.            (strcmp (valve_name, "valve_stm_stuck") == 0))
  344.     if (current.stuck_stm_valve == 0)
  345.       tryvalve2 (¤t.stuck_stm_valve, ¤t.stm_valve, delta);
  346.     else
  347.       unsticktry2 (¤t.stuck_stm_valve, ¤t.stm_valve, delta);
  348.   else if ((strcmp (valve_name, "valve_stg") == 0) ||
  349.            (strcmp (valve_name, "valve_stg_stuck") == 0))
  350.     if (current.stuck_stg_valve == 0)
  351.       tryvalve2 (¤t.stuck_stg_valve, ¤t.stg_valve, delta);
  352.     else
  353.       unsticktry2 (¤t.stuck_stg_valve, ¤t.stg_valve, delta);
  354.   else if ((strcmp (valve_name, "valve_in") == 0) ||
  355.            (strcmp (valve_name, "valve_in_stuck") == 0))
  356.     if (current.stuck_in_valve == 0)
  357.       tryvalve2 (¤t.stuck_in_valve, ¤t.in_valve, delta);
  358.     else
  359.       unsticktry2 (¤t.stuck_in_valve, ¤t.in_valve, delta);
  360. }
  361.  
  362.  
  363. ADDRESS 
  364. MDLget_buffer (vdp)
  365.      ADDRESS vdp;
  366. {
  367.   CHAR *var_name;
  368.  
  369.   var_name = VGvdvarname (vdp);
  370.  
  371.   if (strcmp (var_name, "raw_flow") == 0)
  372.     return (ADDRESS) & current.raw_flow[0];
  373.   if (strcmp (var_name, "produce_flow") == 0)
  374.     return (ADDRESS) & current.produce_flow[0];
  375.  
  376.   if (strcmp (var_name, "raw_material") == 0)
  377.     return (ADDRESS) & current.in_flow;
  378.   if (strcmp (var_name, "input_valve") == 0)
  379.     return (ADDRESS) & current.in_valve;
  380.   if (strcmp (var_name, "hold_tmp_vol") == 0)
  381.     return (ADDRESS) & current.stg_tmp;
  382.   if (strcmp (var_name, "holding_overflow") == 0)
  383.     return (ADDRESS) & current.stg_of_flow;
  384.   if (strcmp (var_name, "inter_valve") == 0)
  385.     return (ADDRESS) & current.stg_valve;
  386.   if (strcmp (var_name, "steam_valve") == 0)
  387.     return (ADDRESS) & current.stm_valve;
  388.   if (strcmp (var_name, "steam_temp") == 0)
  389.     return (ADDRESS) & current.stm_tmp;
  390.   if (strcmp (var_name, "reac_tmp_vol") == 0)
  391.     return (ADDRESS) & current.rv_tmp;
  392.   if (strcmp (var_name, "reaction_overflow") == 0)
  393.     return (ADDRESS) & current.rv_of_flow;
  394.   if (strcmp (var_name, "output_valve") == 0)
  395.     return (ADDRESS) & current.out_valve;
  396.   if (strcmp (var_name, "produce") == 0)
  397.     return (ADDRESS) & current.out_flow;
  398.   if (strcmp (var_name, "stuck_input_valve") == 0)
  399.     return (ADDRESS) & current.stuck_in_valve;
  400.   if (strcmp (var_name, "stuck_inter_valve") == 0)
  401.     return (ADDRESS) & current.stuck_stg_valve;
  402.   if (strcmp (var_name, "stuck_steam_valve") == 0)
  403.     return (ADDRESS) & current.stuck_stm_valve;
  404.   if (strcmp (var_name, "stuck_output_valve") == 0)
  405.     return (ADDRESS) & current.stuck_out_valve;
  406.   if (strcmp (var_name, "inter_flow") == 0)
  407.     return (ADDRESS) & current.stg_out_flow;
  408.   if (strcmp (var_name, "holding_temp") == 0)
  409.     return (ADDRESS) & current.stg_tmp;
  410.   if (strcmp (var_name, "holding_volume") == 0)
  411.     return (ADDRESS) & current.stg_vol;
  412.   if (strcmp (var_name, "reaction_temp") == 0)
  413.     return (ADDRESS) & current.rv_tmp;
  414.   if (strcmp (var_name, "reaction_volume") == 0)
  415.     return (ADDRESS) & current.rv_vol;
  416.  
  417.   return NULL;
  418. }
  419.